"""
Case Type   : cm
Case Name   : cm_ctl start过程中kill -19挂起cm_agent进程
Create At   : 2024-07
Owner       : haomeng
Description :
    1、查看集群状态
    2、停止备节点dn实例进程
    3、执行cm_ctl start拉起被停止节点
    4、在start执行过程中，kill -19 挂起cm_agent进程
    5、查看集群状态
    6、查看启停标志文件
    7、再次执行cm_ctl start操作，查看集群状态
    8、查看启停标志文件
    9、恢复集群初始状态
Expect      :
    1、集群所有节点状态正常，显示Normal
    2、stop成功
    3、拉起操作执行成功
    4、挂起cm_agent进程成功
    5、集群状态正常
    6、文件不存在
    7、拉起集群成功，集群状态正常
    8、文件不存在
    9、恢复集群初始状态成功
History     :
"""

import os
import time
import unittest

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != Primary_SH.get_node_num(), '需1主2备环境，否则不执行')
class CmCtl(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.comsh = CommonSH('PrimaryDbUser')
        self.com = Common('PrimaryDbUser')
        self.pri_user = Node('PrimaryDbUser')
        self.constant = Constant()

    def test_cm(self):
        text = '----step1:查看集群状态; expect:集群状态正常,DN主在节点1----'
        self.log.info(text)

        status = self.comsh.exec_cm_ctl('query', '-Cv', '-z ALL')
        self.log.info(status)
        AZ_status = status.splitlines()[-1]
        self.log.info(AZ_status)
        self.assertIn("cluster_state   : Normal", status)

        text = '----step2:停止备节点dn实例进程; expect:stop成功----'
        self.log.info(text)

        stop = self.comsh.exec_cm_ctl('stop', '-n 2',
                                      f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(stop)

        text = '-----step3:执行cm_ctl start拉起被停止节点 expect:拉起操作执行成功-----'
        self.log.info(text)

        start_cmd = f'start -n 2 -D {macro.DB_INSTANCE_PATH}'
        start_res = ComThread(self.comsh.exec_cm_ctl, args=(start_cmd,))
        start_res.setDaemon(True)
        start_res.start()
        time.sleep(1)

        text = '-----step4:在start执行过程中，kill -19 挂起cm_agent进程' \
               ' expect:挂起cm_agent进程成功-----'
        self.log.info(text)

        cm_pid = self.com.get_pid(self.pri_user, 'cm_agent')
        self.log.info(cm_pid)

        kill_cmd = f'kill -19 {cm_pid}'
        kill_cmd_res = ComThread(self.com.get_sh_result,
                               args=(self.pri_user, kill_cmd,))
        kill_cmd_res.setDaemon(True)
        kill_cmd_res.start()

        start_res.join()
        start_result = start_res.get_result()
        self.log.info(start_result)
        kill_result = kill_cmd_res.get_result()
        self.log.info(kill_result)
        self.assertIn(self.constant.cm_start_instance_success_msg, start_result, '拉起节点失败')
        self.assertEqual('', kill_result, '挂起失败')

        text = '------step5:查看集群状态; expect:状态正常------'
        self.log.info(text)

        time.sleep(5)
        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn("cluster_state   : Normal", status)

        text = '------step6:查看启停标志文件  expect:文件不存在------'
        self.log.info(text)

        file_path = f'ls {macro.GAUSSHOME_BIN_PATH}/cluster_manual_start*'
        cat_file1 = self.pri_user.sh(file_path).result()
        self.log.info(cat_file1)
        self.assertIn('No such file or directory', cat_file1, '启停标志文件存在')

        text = '-----step7:再次start拉起集群  expect:拉起集群成功------'
        self.log.info(text)

        start = self.comsh.exec_cm_ctl('start')
        self.log.info(start)
        self.assertIn(self.constant.cm_start_success_msg, start, '拉起节点失败')

        text = '------step8:查看启停标志文件  expect:文件不存在------'
        self.log.info(text)

        cat_file2 = self.pri_user.sh(file_path).result()
        self.log.info(cat_file2)
        self.assertIn('No such file or directory', cat_file2, '启停标志文件存在')

    def tearDown(self):
        text = '------step9:恢复集群初始状态; expect:恢复集群状态成功------'
        self.log.info(text)

        time.sleep(30)
        status = self.comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        p_status = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        if 'Primary' in p_status:
            self.log.info('---集群状态正常，无需恢复为初始状态---')
        else:
            recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
            self.log.info(recovery)

            self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                          '切换失败')

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '状态异常')
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '状态异常')
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '状态异常')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
